﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;

namespace VisualRibbonEditor
{
	public partial class NewGroupDialog : UserControl, IDialog
	{
		private XElement _groupsElement;

		const string PREFIX_DEFAULT = "Company Name";

		public NewGroupDialog( XElement groupsElement )
		{
			_groupsElement = groupsElement;
			InitializeComponent();

			//set up ID;
			string prefix = MainWindow.CurrentSolution.GetIdPrefix() ?? string.Empty;

			if (string.IsNullOrEmpty(prefix))
			{
				//unable to determine what the "company" prefix is, so we have to allow the user to enter it.
				prefixTextbox.Visibility = System.Windows.Visibility.Visible;
				prefixTextbox.Text = PREFIX_DEFAULT;
			}
			else
			{
				//company prefix was determined by looking at the other buttons, so we can just display it.
				//(dont allow user to enter a different prefix into the prefixtextbox)
				prefixTextbox.Visibility = System.Windows.Visibility.Visible;
				prefixTextbox.Text = prefix;
			}

			string newGroupId = groupsElement.Attribute("Id").Value;
			if (newGroupId.StartsWith("Mscrm"))
			{
				newGroupId = newGroupId.Substring(5);
			}
			if (newGroupId.EndsWith("Groups"))
			{
				newGroupId = newGroupId.Substring(0, newGroupId.Length - 6);
			}
			if (!newGroupId.EndsWith("."))
			{
				newGroupId = newGroupId + ".";
			}
		 
			idPrefix.Text = newGroupId;
		}

		private void OKButton_Click(object sender, RoutedEventArgs e)
		{
			string id = GetValidId();
			if (id == null)
			{
				//invalid 
				return;
			}

			//InsertAllNewButtonXml(id, IdTextbox.Text);
			InsertNewGroup(id);

			if (DialogClosed != null)
			{
				DialogClosed(IdTextbox.Text);
			}
		}

		private void InsertNewGroup(string groupId)
		{
			///////////////////////////////////////////////////////////////
			//Insert group xml into basexml: 
			XElement group = new XElement("Group");
			group.SetAttributeValue("Id", groupId);
			group.SetAttributeValue("Command", "Mscrm.Enabled");
			group.SetAttributeValue("Template", "Mscrm.Templates.Flexible2");
			group.SetAttributeValue("Sequence", "100");
			group.SetAttributeValue("Title", "$LocLabels:" + groupId + ".TitleText");
			group.SetAttributeValue("Description", "$LocLabels:" + groupId + ".DescriptionText");
			_groupsElement.Add(group);
			XElement controls = new XElement("Controls");
			controls.SetAttributeValue("Id", groupId + ".Controls");
			group.Add(controls);


			////////////////////////////////////////////////////
			//Insert scales into basexml
			XElement tab = _groupsElement.Ancestors("Tab").FirstOrDefault();
			XElement scaling = tab.Element("Scaling");

			//add the maxsize scale 
			XElement maxSize = new XElement("MaxSize");
			maxSize.SetAttributeValue("Id", groupId + ".MaxSize");
			maxSize.SetAttributeValue("GroupId", groupId);
			maxSize.SetAttributeValue("Sequence", "10");
			maxSize.SetAttributeValue("Size", "LargeMedium");
			scaling.Add(maxSize);

			//add the popup scale
			XElement popup = new XElement("Scale");
			popup.SetAttributeValue("Id", groupId + ".Scale.Popup");
			popup.SetAttributeValue("GroupId", groupId);
			popup.SetAttributeValue("Sequence", "300");
			popup.SetAttributeValue("Size", "Popup");
			scaling.Add(popup);

			/////////////////////////////////////////////////////////////////
			//set the loclabels in the diffXml
			string title = Helpers.AddSpaces(IdTextbox.Text.Trim());
			Helpers.SetLocLabelTextById(groupId + ".TitleText", Connection.CurrentConnection.BaseLanguage, title);
			Helpers.SetLocLabelTextById(groupId + ".DescriptionText", Connection.CurrentConnection.BaseLanguage, title);

			//add the controls (the group and the 2 scaling elements) to the DiffXml.
			Helpers.AddCustomActionToDiffXml(group);
			Helpers.AddCustomActionToDiffXml(maxSize);
			Helpers.AddCustomActionToDiffXml(popup);
		}


		/// <summary>
		/// Validates the ID entered into the dialog and returns the ID if its valid.
		/// returns NULL if it is not valid.
		/// </summary>
		private string GetValidId()
		{

			if (string.IsNullOrEmpty(IdTextbox.Text))
			{
				MessageBox.Show("You must specify an ID for the new button");
				return null;
			}

			if (string.IsNullOrWhiteSpace(prefixTextbox.Text))
			{
				MessageBox.Show("You must specify a full ID, including a prefix (i.e., company or organization name).");
				return null;
			}

			string newId = string.Empty;
			newId += prefixTextbox.Text;			 
			newId += idPrefix.Text;
			newId += IdTextbox.Text;

			string validchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_.{}!";
			foreach (char c in newId)
			{
				if (!validchars.Contains(c))
				{
					MessageBox.Show("Id must be alphanumeric or underscore, with no spaces.");
					return null;
				}
			}

			if (IdIsInUse(newId))
			{
				MessageBox.Show("The Id \"" + newId + "\" is already in use.");
				return null;
			}

			return newId;
		}


		/// <summary>
		/// Returns true if the ID given is already in use anywhere in the ribbon xml.
		/// </summary>
		private bool IdIsInUse(string id)
		{
			//check to see if the id or id.command is already used in the base xml file
			XElement baseRoot = _groupsElement.Ancestors().Last();
			foreach (XAttribute att in baseRoot.Descendants().Attributes("Id"))
			{
				if (string.Compare(att.Value, id, StringComparison.InvariantCultureIgnoreCase) == 0)
					return true;
				if (string.Compare(att.Value, id + ".Command", StringComparison.InvariantCultureIgnoreCase) == 0)
					return true;
			}

			//check to see if the id (or the id plus any of the suffixes) is already used in the diff xml.
			XElement diffRoot = MainWindow.CurrentSolution.RibbonDiffXml;
			foreach (XAttribute att in diffRoot.Descendants().Attributes("Id"))
			{
				if (string.Compare(att.Value, id, StringComparison.InvariantCultureIgnoreCase) == 0)
					return true;
				if (string.Compare(att.Value, id + ".Command", StringComparison.InvariantCultureIgnoreCase) == 0)
					return true;
				if (string.Compare(att.Value, id + ".CustomAction", StringComparison.InvariantCultureIgnoreCase) == 0)
					return true;
				if (string.Compare(att.Value, id + ".LabelText", StringComparison.InvariantCultureIgnoreCase) == 0)
					return true;
				if (string.Compare(att.Value, id + ".Description", StringComparison.InvariantCultureIgnoreCase) == 0)
					return true;
			}

			return false;
		}

		/// <summary>
		/// user clicked the cancel button. Call DialogClose event with NULL to indicate a cancel.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void CancelButton_Click(object sender, RoutedEventArgs e)
		{
			if (DialogClosed != null)
			{
				DialogClosed(null);
			}
		}

		public event CloseDialogHandler DialogClosed;

		private void UserControl_Loaded(object sender, RoutedEventArgs e)
		{
			if (prefixTextbox.Text == PREFIX_DEFAULT)
			{
				prefixTextbox.Focus();
				prefixTextbox.SelectAll();
			}
			else
			{
				IdTextbox.Focus();
			}
		}

		private void IdTextbox_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.Key == Key.Enter) OKButton_Click(sender, new RoutedEventArgs());
		}

		private void NewGroupDialog_KeyUp(object sender, KeyEventArgs e)
		{
			switch (e.Key) //
			{
				// ESC
				case Key.Escape:
					if (DialogClosed != null) DialogClosed(null);
					break;
				default:
					break;
			}
		}
	}
}